/*
 * Copyright (c) 2012 Andrea De Rinaldis <ozioso at ipignoli.dyndns.org>
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

package org.dyndns.ipignoli.droidcruise;

import org.dyndns.ipignoli.droidcruise.controller.DeviceIdentifier;
import org.dyndns.ipignoli.droidcruise.controller.LocationPostOld;
import org.dyndns.ipignoli.droidcruise.controller.MyAsyncTask;
import org.dyndns.ipignoli.droidcruise.controller.MyAsyncTask.EndTaskListener;
import org.dyndns.ipignoli.droidcruise.controller.RecordingDeletion;
import org.dyndns.ipignoli.droidcruise.controller.RecordingLoad;
import org.dyndns.ipignoli.droidcruise.controller.RecordingRetrieve;
import org.dyndns.ipignoli.droidcruise.controller.RoutePostOld;
import org.dyndns.ipignoli.droidcruise.db.MyHelper;
import org.dyndns.ipignoli.droidcruise.http.LocationPoster;
import org.dyndns.ipignoli.droidcruise.http.RoutePoster;
import org.dyndns.ipignoli.droidcruise.recording.Recording;
import org.dyndns.ipignoli.droidcruise.ui.RecordingCursorAdapter;
import org.dyndns.ipignoli.droidcruise.util.CommonStore;
import android.app.AlertDialog;
import android.app.ListActivity;
import android.content.DialogInterface;
import android.database.Cursor;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.SimpleCursorAdapter;
import android.widget.Toast;


public class RecordingList extends ListActivity{
  private static final int    MENU_SEND   = Menu.FIRST;
  private static final int    MENU_DELETE = Menu.FIRST + 1;

  private MyHelper            dbHelper;
  private SimpleCursorAdapter cursorAdapter;

  private String              deviceID;
  private RoutePoster         routePoster;
  private LocationPoster      tutorPoster;
  private LocationPoster      radarPoster;

  private boolean             ended;

  @Override
  protected void onCreate(Bundle bundle){
    super.onCreate(bundle);

    ended = false;

    dbHelper = new MyHelper(this);

    deviceID = null;

    setTitle(R.string.Recording_list);

    setContentView(R.layout.recording_list);

    registerForContextMenu(getListView());
  }

  @Override
  protected void onResume(){
    super.onResume();
    // MyContext.initialize(this);
    restoreState();
    updateData();
  }

  @Override
  protected void onPause(){
    super.onPause();
    if(!ended)
      saveState();
  }

  private void saveState(){
    if(deviceID != null)
      CommonStore.getInstance().put(CommonStore.DROID_CRUISE_DEVICE_ID,
          deviceID);
  }

  private void restoreState(){
    if(CommonStore.getInstance()
        .containsKey(CommonStore.DROID_CRUISE_DEVICE_ID)){
      deviceID =
          (String)CommonStore.getInstance().get(
              CommonStore.DROID_CRUISE_DEVICE_ID);
      routePoster = new RoutePoster(deviceID);
      tutorPoster = new LocationPoster(deviceID, Recording.TUTOR_TYPE);
      radarPoster = new LocationPoster(deviceID, Recording.RADAR_TYPE);
    }
    else
      new DeviceIdentifier(this,
          new DeviceIdentifier.EndTaskListener<String>(){
            @Override
            public void notify(String result){
              if(result == null)
                return;
              deviceID = result;
              routePoster = new RoutePoster(deviceID);
              tutorPoster = new LocationPoster(deviceID, Recording.TUTOR_TYPE);
              radarPoster = new LocationPoster(deviceID, Recording.RADAR_TYPE);
            }
          }).execute((Object[])null);
  }

  @Override
  public void onCreateContextMenu(ContextMenu menu, View v,
      ContextMenuInfo menuInfo){
    super.onCreateContextMenu(menu, v, menuInfo);
    menu.add(0, MENU_SEND, 0, R.string.Send_recording);
    menu.add(0, MENU_DELETE, 1, R.string.Delete_recording);
  }

  @Override
  public boolean onContextItemSelected(MenuItem item){
    switch(item.getItemId()){
      case MENU_SEND:
        postRecording(((AdapterContextMenuInfo)item.getMenuInfo()).id);
        return true;

      case MENU_DELETE:
        deleteRecording(((AdapterContextMenuInfo)item.getMenuInfo()).id);
        return true;
    }

    return super.onContextItemSelected(item);
  }

  @Override
  public void finish(){
    ended = true;
    super.finish();
  }

  private SimpleCursorAdapter getCursorAdapter(Cursor cursor){
    if(cursorAdapter == null)
      cursorAdapter =
          new RecordingCursorAdapter(this, R.layout.row_recording,
              cursor, R.id.recording_icon, R.id.recording_date,
              R.id.recording_locality);

    cursorAdapter.changeCursor(cursor);

    return cursorAdapter;
  }

  private void postRecording(long id){
    new RecordingRetrieve(this,
        new RecordingRetrieve.EndTaskListener<Recording>(){
          @Override
          public void notify(final Recording recording){
            if(recording == null)
              return;

            if(!recording.getSent()){
              reallyPostRecording(recording);
              return;
            }

            (new AlertDialog.Builder(RecordingList.this))
                .setIcon(android.R.drawable.ic_dialog_alert)
                .setTitle(R.string.Send_recording)
                .setCancelable(false)
                .setMessage(R.string.Selected_recording_as_already_been_sent)
                .setPositiveButton(R.string.ok,
                    new DialogInterface.OnClickListener(){
                      @Override
                      public void onClick(DialogInterface dialog, int which){
                        reallyPostRecording(recording);
                      }
                    }).setNegativeButton(R.string.Cancel, null).show();
          }
        }).execute(id);
  }

  private void reallyPostRecording(Recording recording){
    MyAsyncTask<Long, Integer, Boolean> poster = null;

    switch(recording.getType()){
      case Recording.RADAR_TYPE:
        if(radarPoster == null){
          Toast.makeText(RecordingList.this, R.string.Device_not_ready,
              Toast.LENGTH_SHORT).show();
          return;
        }

        poster =
            new LocationPostOld(RecordingList.this,
                new EndTaskListener<Boolean>(){
                  @Override
                  public void notify(Boolean result){
                    if(!result)
                      return;
                    Toast.makeText(RecordingList.this,
                        R.string.Information_sent_Thanks, Toast.LENGTH_SHORT)
                        .show();
                    updateData();
                  }
                }, radarPoster);
        break;

      case Recording.TUTOR_TYPE:
        if(tutorPoster == null){
          Toast.makeText(RecordingList.this, R.string.Device_not_ready,
              Toast.LENGTH_SHORT).show();
          return;
        }

        poster =
            new LocationPostOld(RecordingList.this,
                new EndTaskListener<Boolean>(){
                  @Override
                  public void notify(Boolean result){
                    if(!result)
                      return;
                    Toast.makeText(RecordingList.this,
                        R.string.Information_sent_Thanks, Toast.LENGTH_SHORT)
                        .show();
                    updateData();
                  }
                }, tutorPoster);
        break;

      case Recording.ROUTE_TYPE:
        if(routePoster == null){
          Toast.makeText(RecordingList.this, R.string.Device_not_ready,
              Toast.LENGTH_SHORT).show();
          return;
        }

        poster =
            new RoutePostOld(RecordingList.this,
                new EndTaskListener<Boolean>(){
                  @Override
                  public void notify(final Boolean result){
                    if(!result)
                      return;
                    Toast.makeText(RecordingList.this,
                        R.string.Information_sent_Thanks, Toast.LENGTH_SHORT)
                        .show();
                    updateData();
                  }
                }, routePoster);
        break;
    }

    if(poster != null)
      poster.execute(recording.getId());
  }

  private void deleteRecording(long id){
    new RecordingRetrieve(this,
        new RecordingRetrieve.EndTaskListener<Recording>(){
          @Override
          public void notify(final Recording recording){
            if(recording == null)
              return;

            (new AlertDialog.Builder(RecordingList.this))
                .setIcon(android.R.drawable.ic_dialog_alert)
                .setTitle(R.string.Delete_recording)
                .setCancelable(false)
                .setMessage(R.string.Really_delete_selected_recording)
                .setPositiveButton(R.string.ok,
                    new DialogInterface.OnClickListener(){
                      @Override
                      public void onClick(DialogInterface dialog, int which){
                        new RecordingDeletion(RecordingList.this,
                            new RecordingDeletion.EndTaskListener<Boolean>(){
                              @Override
                              public void notify(Boolean result){
                                if(result == null)
                                  return;
                                Toast.makeText(RecordingList.this,
                                    R.string.Recording_deleted,
                                    Toast.LENGTH_SHORT).show();
                                updateData();
                              }
                            }).execute(recording);
                      }
                    }).setNegativeButton(R.string.Cancel, null).show();
          }
        }).execute(id);
  }

  private void updateData(){
    new RecordingLoad(this, new RecordingLoad.EndTaskListener<Cursor>(){
      @Override
      public void notify(final Cursor cursor){
        setListAdapter(getCursorAdapter(cursor));
      }
    }).execute((Object[])null);
  }
}
